<template>
  <div>
    <el-form-item>
      <el-button style="width: 100%" @click="editFormula">编辑公式</el-button>
    </el-form-item>

    <drag-dialog
      :close-on-click-modal="false"
      :show-close="false"
      title="公式编辑"
      v-model="showFormula"
    >
      <div>
        <div>{{ localData.label }}</div>
        <div>
          <div
            class="ant-input"
            id="edit"
            ref="formulaText"
            contenteditable="true"
            placeholder="请输入链接"
            v-html="formulaText"
            @input="inputValueFun"
          ></div>
          <!-- <button @click="onAddItem('tag')">添加标签</button> -->
        </div>
      </div>
      <div class="formulaData">
        <div style="width: 35%">
          <div>变量</div>
          <div class="">
            <div v-for="(item, index) in formJson.column" :key="index" style="cursor: pointer">
              <div v-if="!item.children" class="funStyle">
                <el-button
                  link
                  @click="onAddItem('tag', item.label, item.prop, item)"
                  style="cursor: pointer; display: block; color: #9c9ea7"
                  :key="index"
                >{{ item.label }}</el-button
                >
              </div>

              <div v-else>
                <div v-for="(self, idx) in item.children.column" :key="idx" class="funStyle">
                  <el-button
                    link
                    @click="
                      onAddItem('tag', item.label + '.' + self.label, item.prop + '_' + self.prop)
                    "
                    style="cursor: pointer; display: block; color: #9c9ea7"
                  >{{ item.label }}.{{ self.label }}</el-button
                  >
                </div>
              </div>
            </div>
          </div>
        </div>
        <div style="width: 25%">
          <div>函数</div>
          <div
            class="funStyle"
            v-for="(item, index) in formulaArr"
            :key="index"
            @mouseenter="funInfo(item)"
          >
            <el-button
              link
              @click="onAddItem('fun', item.funName, item)"
              style="cursor: pointer; display: block; color: #9c9ea7"
            >{{ item.funName }}</el-button
            >
          </div>
        </div>
        <div style="width: 40%">
          <div>说明</div>
          <div>
            <div>{{ funInfoData.eg }}</div>
            <div>{{ funInfoData.usage }}</div>
            <div>{{ funInfoData.explainText }}</div>
          </div>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closeEditFormula">取 消</el-button>
          <el-button type="primary" @click="sure()">确 定</el-button>
        </span>
      </template>
    </drag-dialog>
  </div>
</template>
<script>
import formulaArr from '../formulaArr'
import * as formulajs from '@formulajs/formulajs'
export default {
  props: {
    data: {
      type: Object,
      default: () => {}
    },
    formJson: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      showFormula: false,
      options: [
        {
          value: 1,
          label: '公式编辑'
        }
      ],
      savedRange: null,
      formulaArr,
      dialogVisible: true,
      inputText: '',
      inputValue: '',
      lastEditRange: '',
      funInfoData: {},
      formulaText: '',
      localData: {}
    }
  },
  watch: {
    data: {
      handler(newVal, oldVal) {
        if (newVal) {
          this.localData = newVal
        }
        if (newVal.formula && newVal.formula.includes('&gt;')) {
          this.localData.formula = newVal.formula.replace(/&gt;/g, '>')
        }
        if (newVal.formula && newVal.formula.includes('&lt;')) {
          this.localData.formula = newVal.formula.replace(/&lt;/g, '<')
        }

        // this.$set(this.localData,'formula',newVal.formula)
      },
      deep: true,
      immediate: true,
      textData: ''
    },
    showFormula: {
      handler(newValue, oldValue) {
        if (newValue) {
          this.formulaText = this.localData.formulaTag
        }
      }
    },
    localData: {
      handler(newVal) {
        this.$emit('update:data', newVal)
      },
      deep: true
    }
  },
  mounted() {
    // 注册光标移动事件
    document.addEventListener('selectionchange', this.HandleSelectionChange, false)
    // 因为是组件，接收数据显示
    this.formulaText = this.value
  },

  created() {},
  methods: {
    inputValueFun(e) {
      console.log(this.$refs.formulaText, 'e')
      var parentElement = document.getElementById('edit') // 获取父标签
      var childElements = parentElement.children
      this.getTextNode(childElements, 'onlyInput')
      // this.getTextNode(childElements)
    },
    closeEditFormula() {
      this.inputText = ''
      this.showFormula = false
    },
    editFormula() {
      this.showFormula = true
    },
    // 保留当前选择的范围
    HandleSelectionChange() {
      let sel = window.getSelection && window.getSelection()
      if (sel && sel.rangeCount) {
        this.savedRange = sel.getRangeAt(0)
      }
    },
    // 添加参数到链接中
    onAddItem(type, text, prop, item = {}) {
      this.textData = ''
      let data = text,
        tag,
        name
      name = prop
      if (item.type && item.type === 'select') {
        name = '$' + prop
      }
      if (type === 'fun') {
        tag = `<span>${data}</sapn>`
      } else {
        tag = `<input
          class="tag_style"
          type="button"
          name=${name}
          value=${data}
        />`
      }
      this.pasteHtmlAtCaret(tag)
      var parentElement = document.getElementById('edit') // 获取父标签
      var childElements = parentElement.children
      this.getTextNode(childElements)
    },
    // nodeName 是 input  取  defaultValue    nodeName text 取 data  textData
    getTextNode(node, type) {
      if(type == 'onlyInput'){
        this.textData = ''
      }

      node.forEach((item) => {
        if (item.nodeName == 'INPUT') {
          this.textData = this.textData + item.name
        } else if (item.nodeName == '#text') {
          this.textData = this.textData + item.data
        }
        if (item.childNodes && item.childNodes.length > 0) {
          this.getTextNode(item.childNodes)
        }
      })
    },
    // 获取光标，插入html
    pasteHtmlAtCaret(html) {
      console.log(html)
      let sel, range
      // IE9 and non-IE
      if (window.getSelection) {
        sel = window.getSelection()
        if (sel && sel.rangeCount === 0 && this.savedRange !== null) sel.addRange(this.savedRange) // 保留光标在文字中间插入的最后位置
        if (sel && sel.rangeCount) range = sel.getRangeAt(0)
        if (['', null, undefined].includes(range)) {
          // 如果div没有光标，则在div内容末尾插入
          range = this.keepCursorEnd(true).getRangeAt(0)
        } else {
          const contentRange = document.createRange()
          contentRange.selectNode(this.$refs.formulaText)
          // 对比range，检查光标是否在输入范围内
          const compareStart = range.compareBoundaryPoints(Range.START_TO_START, contentRange)
          const compareEnd = range.compareBoundaryPoints(Range.END_TO_END, contentRange)
          const compare = compareStart !== -1 && compareEnd !== 1
          if (!compare) range = this.keepCursorEnd(true).getRangeAt(0)
        }
        let input = range.createContextualFragment(html)
        let lastNode = input.lastChild // 记录插入input之后的最后节点位置
        range.insertNode(input)
        if (lastNode) {
          // 如果有最后的节点
          range = range.cloneRange()
          range.setStartAfter(lastNode)
          range.collapse(true)
          sel.removeAllRanges()
          sel.addRange(range)
        }
      } else if (document['selection'] && document['selection'].type !== 'Control') {
        // IE < 9
        document['selection'].createRange().pasteHTML(html)
      }
    },
    keepCursorEnd(isReturn) {
      // const div = document.getElementById('edit');
      if (window.getSelection) {
        // ie11 10 9 firefox safari
        this.$refs.formulaText.focus()
        let sel = window.getSelection() // 创建range
        sel.selectAllChildren(this.$refs.formulaText) // range 选择obj下所有子内容
        sel.collapseToEnd() // 光标移至最后
        if (isReturn) return sel
      } else if (document['selection']) {
        // ie9以下
        let sel = document['selection'].createRange() // 创建选择对象
        sel.moveToElementText(this.$refs.formulaText) // range定位到编辑器
        sel.collapse(false) // 光标移至最后
        sel.select()
        if (isReturn) return sel
      }
    },
    // changeValue(e) {
    //   // 去除用户在输入时，主动输入的换行符
    //   const formulaText = e.target.innerHTML.toString().replace(/<br>/g, '')
    //   this.$emit('input', formulaText);
    // },

    // 处理粘贴时消除样式
    HandlePaste(e) {
      e.stopPropagation()
      e.preventDefault()
      var text = ''
      var event = e.originalEvent || e
      if (event.clipboardData && event.clipboardData.getData) {
        text = event.clipboardData.getData('text/plain')
      } else if (window['clipboardData'] && window['clipboardData'].getData) {
        text = window['clipboardData'].getData('Text')
      }
      if (document.queryCommandSupported('insertText')) {
        document.execCommand('insertText', false, text)
      } else {
        document.execCommand('paste', false, text)
      }
    },

    funInfo(info) {
      this.funInfoData = info
    },
    sure() {
      let getTag = this.$refs.formulaText
      this.localData.formula = this.textData
      this.localData.formulaTag = getTag.innerHTML
      // this.$set(this.localData,'formula',this.textData)
      // this.$set(this.localData,'formulaTag',getTag.innerHTML)
      this.showFormula = false
    },
    changeFormula(e) {
      this.inputText = e
      this.localData.formula = this.inputText
      // this.$set(this.localData,'formula',this.inputText);
    },
    sumAdd(str, item, index = -1) {
      this.inputText = this.localData.formula || ''
      // 下拉框字段
      let formateStr = item.type == 'select' ? '$' + str : str
      str = typeof str === 'string' ? formateStr : JSON.stringify(formateStr)
      // // 设置光标起始位置
      let startPos = document.getElementById('input').selectionStart
      let endPos = document.getElementById('input').selectionEnd
      this.inputText = this.addStrPos(this.inputText, startPos, endPos, str)
      this.localData.formula = this.inputText
      // this.$set(this.localData,'formula',this.inputText);
      // // 提前得到更新后的光标位置
      this.$nextTick(() => {
        document.getElementById('input').selectionStart = startPos + str.length
        document.getElementById('input').selectionEnd = startPos + str.length
      })
      document.getElementById('input').focus()
    },
    addStrPos(str, startind, endind, newstr) {
      return str.slice(0, startind) + newstr + str.slice(endind)
    }
  }
}
</script>
<style lang="scss" scoped>
:deep(.tag_style) {
  background: rgb(234, 242, 253) !important;
  color: rgb(47, 125, 235) !important;
  border: none !important;
}
// /deep/.el-button{
//   margin-left: 0px !important;
// }
:deep(.drag-dialog__body) {
  padding: 0px 20px !important;
}
.formulaData {
  display: flex;
}
.funStyle {
  // padding: 5px 3px;
  color: #9c9ea7 !important;
  .el-button {
    width: 100% !important;
    text-align: left !important;
  }
}
.funStyle:hover {
  background: #f0f1f4;
}
.ant-input {
  width: 100%;
  padding: 10px 10px;
  border-radius: 10px;
  height: 200px;
  border: 1px solid #d9d9d9;
}
</style>
